package org.md.budzik.problems;

import java.util.HashMap;
import java.util.Map;

import org.md.budzik.R;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;

/**
 * Template provider dla bazy z zadaniami.
 * Udostępnia metody umożliwiające pobieranie rekordów z SQLite.
 * @author Wiezzel, Saephir (poprawki)
 *
 */
public class ProblemTemplateProvider extends ContentProvider {

	private static final String AUTHORITY = "org.md.budzik.problems.ProblemTemplateProvider";
	private static final String TABLE_NAME = "templates";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
	
	private static final int TEMPLATES = 1;
	private static final int TEMPLATES_ID = 2;
	private static final UriMatcher uriMatcher;
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(AUTHORITY, TABLE_NAME, TEMPLATES);
		uriMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", TEMPLATES_ID);
	}
	
	public static final class Constants implements BaseColumns {
		public static final Uri CONTENT_URI = Uri.parse(AUTHORITY + "/constants");
		public static final String _ID = "_id";
		public static final String TEXT = "text";
		public static final String VARIABLES = "variables";
		public static final String FORMULA = "formula";
		public static final String DEFAULT_SORT_ORDER = "_id";
	}
	
	private static final Map<String,String> templatesProjection;
	static {
		templatesProjection = new HashMap<String,String>();
		templatesProjection.put(Constants._ID, Constants._ID);
		templatesProjection.put(Constants.TEXT, Constants.TEXT);
		templatesProjection.put(Constants.VARIABLES, Constants.VARIABLES);
		templatesProjection.put(Constants.FORMULA, Constants.FORMULA);
	}
	
	/**
	 * Klasa pomocnicza tworząca interfejs obsługi bazy.
	 * @author Wiezel
	 *
	 */
	private static class DatabaseHelper extends SQLiteOpenHelper {
		
		private static final String DATABASE_NAME = "problemtemplates.db";
		private static final int DATABASE_VERSION = 1;
		
		private Resources resources;

		public DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
			resources = context.getResources();
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + Constants._ID + 
				" INTEGER PRIMARY KEY AUTOINCREMENT, " + Constants.TEXT + " TEXT, " +
				Constants.VARIABLES + " TEXT, " + Constants.FORMULA + " TEXT);");
			for (String problem : resources.getStringArray(R.array.basic_problems))
				db.execSQL("INSERT INTO " + TABLE_NAME + " (" + Constants.TEXT + ", " +
					Constants.VARIABLES + ", " + Constants.FORMULA + ") VALUES" + problem);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
			onCreate(db);
		}
		
	}
	
	private DatabaseHelper dbHelper;

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		int count;
		
		int match = uriMatcher.match(uri);
		if (match == TEMPLATES) 
			count = database.delete(TABLE_NAME, selection, selectionArgs);
		else if (match == TEMPLATES_ID)
			count = database.delete(TABLE_NAME, Constants._ID + "=" + uri.getLastPathSegment() + 
					(TextUtils.isEmpty(selection) ? "" : " AND (" + selection + ")"), selectionArgs);
		else
			throw new IllegalArgumentException("Unkonown URI: " + uri);
		
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch(uriMatcher.match(uri)) {
			case TEMPLATES:
				return "vnd.android.cursor.dir/vnd.problems.template";
			case TEMPLATES_ID:
				return "vnd.android.cursor.item/vnd.problems.template";
			default:
				return null;
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		
		if (uriMatcher.match(uri) == UriMatcher.NO_MATCH)
			throw new IllegalArgumentException("Unknown URI: " + uri);
		
		ContentValues contentValues;
		if (values != null)
			contentValues = new ContentValues(values);
		else
			contentValues = new ContentValues();
		
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		long id = database.insert(TABLE_NAME, Constants.TEXT, contentValues);
		if (id > 0) {
			Uri newUri = ContentUris.withAppendedId(CONTENT_URI, id);
			getContext().getContentResolver().notifyChange(newUri, null);
			return newUri;
		}
		else
			throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		
		int match = uriMatcher.match(uri);
		if ((match == TEMPLATES) || (match == TEMPLATES_ID)) {
			queryBuilder.setTables(TABLE_NAME);
			queryBuilder.setProjectionMap(templatesProjection);
			if (match == TEMPLATES_ID)
				queryBuilder.appendWhere(Constants._ID + "=" + uri.getLastPathSegment());
		} else
			throw new IllegalArgumentException("Unkonown URI: " + uri);
		
		String orderBy;
		if (TextUtils.isEmpty(sortOrder))
			orderBy = Constants.DEFAULT_SORT_ORDER;
		else
			orderBy = sortOrder;
		
		SQLiteDatabase database = dbHelper.getReadableDatabase();
		Cursor cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, orderBy);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
			
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

		SQLiteDatabase database = dbHelper.getWritableDatabase();
		int count;
		
		int match = uriMatcher.match(uri);
		if (match == TEMPLATES)
			count = database.update(TABLE_NAME, values, selection, selectionArgs);
		else if (match == TEMPLATES_ID)
			count = database.update(TABLE_NAME, values, Constants._ID + "=" + uri.getLastPathSegment() + 
					(TextUtils.isEmpty(selection) ? "" : " AND (" + selection + ")"), selectionArgs);
		else
			throw new IllegalArgumentException("Unkonown URI: " + uri);
		
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

}
